package org.example3;

import java.lang.reflect.Method;

public class AppThreadTest {
    public static void main(String[] args) throws Exception {

        testRealThread();
        System.out.println("-----------------------------------------------------------------");
        Thread.sleep(20);
        testByOverride();
    }

    public static void testRealThread() throws Exception {

        /** 里面的runnable匿名内部类反编译
         final class AppThreadTest$1
         implements Runnable
         {
         public void run()
         {
         System.out.println("--------  run来自第一个 --------");
         }
         }
         */

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("-------- run来自第一个 --------");
            }
        };

        //class org.example3.AppThreadTest$1
        System.out.println("runnable的类是"+runnable.getClass());

        Thread thread = new Thread(runnable);

        // 注意此时获取的是java.lang.Thread,是真正的线程类.常规调用和反射调用其中的方法均可以
        System.out.println(thread.getClass().getName());
        //常规调用
//        thread.start();  // 注意一个线程只能被start一次
        //反射调用
        Method start0 = thread.getClass().getDeclaredMethod("start0");
        System.out.println("start0方法信息是:" + start0);
        start0.setAccessible(true);
        start0.invoke(thread);
    }

    public static void testByOverride() throws Exception {
        /** 里面的runnable匿名内部类反编译
         final class AppThreadTest$2 extends Thread
         {
         public void run()
         {
         super.run();
         System.out.println("------第二个执行了-----");
         }
         }
         */

        Thread sonThread = new Thread() {
            @Override
            public void run() {
                super.run();
                System.out.println("------第二个执行了-----");
            }
        };

//        sonThread.start(); //常规调用可以


        //注意此时获取的类是  org.example3.AppThreadTest$2 ,不是属于Thread的子类
        System.out.println(sonThread.getClass().getName());

        Method start0 = sonThread.getClass().getDeclaredMethod("start");
        System.out.println("start is " + start0);
        start0.setAccessible(true);
        start0.invoke(sonThread);
    }
}
